<?php
/*********************************************
 *  CPG Dragonfly™ CMS
 *********************************************
	Copyright © since 2010 by CPG-Nuke Dev Team
	http://dragonflycms.org

	Dragonfly is released under the terms and conditions
	of the GNU GPL version 2 or any later version
*/

namespace Poodle\Kernels;

abstract class PushFiles extends \Poodle
{
	protected
		$mtime = 0,
		$f_ext = null, // with dot: '.css', '.js', etc.
		$mime  = 'application/octet-stream',
		$lng   = 'en',
		$cfg   = array(
			'cache_dir'   => null,
			'cache_uri'   => null,
			'design_mode' => false,
			'expires'     => 8035200, // 3 months
		);

	function __construct(array $cfg)
	{
		$this->lng = substr(\Poodle::$UA_LANGUAGES,0,2);

		$this->cfg = array_merge($this->cfg, $cfg);

		$this->CACHE = \Poodle\Cache::factory($this->cfg['cache_uri']);
	}


	protected static function assoc_array_push_before(array &$array, $ref_key, $key)
	{
		$new = array();
		foreach ($array as $k => $v) {
			if ($ref_key===$k) {
				$new[$key] = isset($array[$key])?$array[$key]:null;
			}
			$new[$k] = $v;
		}
		$array = $new;
	}

	protected function getValidFilesList($keys)
	{
		$keys  = is_array($keys) ? $keys : explode(';', $keys);
		$files = $this->missing = array();
		for ($i=0;$i<count($keys);++$i)
		{
			$name = $keys[$i];
			if ($file = $this->findFile($name)) {
				$files[$name] = $file;
				// Process @import rules
				$tmp = file_get_contents($file,false,null,-1,4096);
				if (preg_match_all('#@import[^"]+"([^"]+)"#',$tmp,$m)) {
					foreach ($m[1] as $filename) {
						$filename = str_replace($this->f_ext,'',$filename);
						if (!in_array($filename, $keys)) {
							$keys[] = $filename;
						}
						// imported file should be included before
						// this file as it relies on it
						static::assoc_array_push_before($files,$name,$filename);
					}
				}
				// Add language file
				if ($file = $this->findL10NFile($name)) {
					$files[$name.'~'.$this->lng] = $file;
				}
			}
			else $this->missing[] = $name;
		}
		return $files;
	}

	abstract protected function findFile($filename);

	protected function findL10NFile($filename) { return false; }

	protected function send_file(&$data=null)
	{
		clearstatcache();
		$file = $this->CFile.$this->f_ext;
		$mtime = 0;
		if ($data) {
			$data  = trim($data);
			$mtime = $this->mtime;
			if ($this->CACHE->set($file, $data)) {
				if (function_exists('gzcompress')) {
					$this->CACHE->set($file.'.gz', gzcompress($data,9));
				}
				$mtime = $this->CACHE->mtime($file);
			}
		} else {
			if (!$this->CACHE->exists($file)) { return; }
			$mtime = $this->CACHE->mtime($file);
		}
		if ($mtime < $this->mtime) { return; }

		\Poodle\HTTP\Headers::etag_last_modified($this->ETag.'-'.$mtime, $mtime);
		header('Expires: '.gmdate('D, d M Y H:i:s \G\M\T', time()+$this->cfg['expires']));
		header('Cache-Control: public');
		header('Content-Type: '.$this->mime.'; charset=utf-8');
		if ($data)
		{
			if (\Poodle::$COMPRESS_OUTPUT && function_exists('ob_gzhandler')) { @ob_start('ob_gzhandler'); }
			else { header('Content-Length: '.strlen($data)); }
			exit($data);
		}
		$ext = (\Poodle::$COMPRESS_OUTPUT && !empty($_SERVER['HTTP_ACCEPT_ENCODING']) && stripos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false && is_file($file.'.gz')) ? '.gz' : '';
		if ($this->CACHE->exists($file))
		{
			if ($ext) {
				$file .= $ext;
				header('Content-Encoding: gzip');
				header('Content-Length: '.$this->CACHE->size($file));
			} else if (\Poodle::$COMPRESS_OUTPUT && function_exists('ob_gzhandler')) {
				ob_start('ob_gzhandler');
			} else {
				header('Content-Length: '.$this->CACHE->size($file));
			}
			echo $this->CACHE->get($file);
			exit;
		}
	}

}
